package com.hspedu.innerClass.category;

/**
 * 1.本质是类 ；2.内部类；3.该类没有名字；4.同时还是一个对象
 * 匿名内部来是定义在外部类的局部位置，比如方法中，并且没有类名
 *
 * new 类或接口(参数列表){
 *     类体
 * }
 */
public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer04 outer04 = new Outer04();
        outer04.method();

        //以前的方法，使用多态的向上转型调用
        IA dog = new Dog();
        dog.cry();
    }
}


class Outer04{
    public void method(){


        /**基于接口的匿名内部类
         * 这里创建了接口类型的对象，直接写了方法体，后面还跟了分号;
         */
        IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("老虎叫唤");
            }
        };

        /*
        其实在jdk底层在创建匿名内部类Outer04$1, 然后马上创建了Outer04的实例，并把地址返回给tiger
         class Outer04$1 implements IA {
            @Override
            public void cry() {
                System.out.println("老虎叫唤");
            }
        }
         */
        System.out.println("tiger的运行类型"+tiger.getClass());
        tiger.cry();


        /**
         * 基于类的匿名内部类
         * father编译类型: Father
         * father运行类型: Outer04$2
         * 注意("jack")参数列表会传递给构造器
         */
        Father father = new Father("jack"){
            @Override
            public void test() {
                System.out.println("匿名内部类重写了test方法");
            }
        };
        System.out.println("father对象的运行类型="+father.getClass());


        //基于抽象类的匿名内部类
        new Animal(){

            @Override
            void eat() {
                System.out.println("吃饭");
            }
        };


    }
}

interface IA{//一个接口
    void cry();
}

class Dog implements IA{

    @Override
    public void cry() {
        System.out.println("小狗叫唤");
    }
}

class Father{//一个普通类
    public Father(String name){//构造器
        System.out.println("接收到name=" + name);
    }
    public void test(){//一个方法

    }
}


abstract class Animal{//一个抽象类
    abstract void eat();
}